<template>
  <div class="db-connection-manager">
    <el-dialog
      v-model="dialogVisible"
      :title="isEditing ? '编辑数据库连接' : '新建数据库连接'"
      width="600px"
    >
      <el-form :model="connectionForm" :rules="rules" ref="connectionFormRef" label-width="120px">
        <el-form-item label="名称" prop="name">
          <el-input v-model="connectionForm.name" placeholder="请输入连接名称" />
        </el-form-item>
        
        <el-form-item label="数据库类型" prop="dbType">
          <el-select v-model="connectionForm.dbType" placeholder="请选择数据库类型" style="width: 100%">
            <el-option label="MySQL" value="mysql" />
            <el-option label="PostgreSQL" value="postgresql" />
            <el-option label="Oracle" value="oracle" />
            <el-option label="SQL Server" value="sqlserver" />
          </el-select>
        </el-form-item>
        
        <el-form-item label="主机地址" prop="host">
          <el-input v-model="connectionForm.host" placeholder="例如: localhost 或 192.168.1.1" />
        </el-form-item>
        
        <el-form-item label="端口" prop="port">
          <el-input-number v-model="connectionForm.port" :min="1" :max="65535" controls-position="right" style="width: 100%" />
        </el-form-item>
        
        <el-form-item label="数据库名" prop="databaseName">
          <el-input v-model="connectionForm.databaseName" placeholder="请输入数据库名称" />
        </el-form-item>
        
        <el-form-item label="用户名" prop="username">
          <el-input v-model="connectionForm.username" placeholder="请输入数据库用户名" />
        </el-form-item>
        
        <el-form-item label="密码" prop="password">
          <el-input 
            v-model="connectionForm.password" 
            type="password" 
            placeholder="请输入数据库密码"
            show-password
          />
        </el-form-item>
        
        <el-form-item>
          <el-checkbox v-model="connectionForm.isDefault">设为默认连接</el-checkbox>
        </el-form-item>
      </el-form>
      
      <div class="dialog-footer">
        <el-button @click="testCurrentConnection" :loading="testing">测试连接</el-button>
        <el-button @click="closeDialog">取消</el-button>
        <el-button type="primary" @click="saveConnection" :loading="saving">
          {{ isEditing ? '保存修改' : '创建连接' }}
        </el-button>
      </div>
    </el-dialog>
    
    <div class="connection-manager-header">
      <h3>数据库连接管理</h3>
      <el-button type="primary" @click="openCreateDialog">添加新连接</el-button>
    </div>
    
    <div v-if="loading" class="loading-wrapper">
      <el-skeleton :rows="4" animated />
    </div>
    
    <div v-else-if="connections.length === 0" class="empty-state">
      <el-empty description="暂无数据库连接">
        <el-button type="primary" @click="openCreateDialog">添加新连接</el-button>
      </el-empty>
    </div>
    
    <div v-else class="connections-list">
      <el-card 
        v-for="conn in connections" 
        :key="conn.id" 
        class="connection-card"
        :class="{ 'is-default': conn.isDefault }"
      >
        <div class="connection-header">
          <h4>{{ conn.name }}</h4>
          <el-tag v-if="conn.isDefault" type="success" size="small">默认</el-tag>
        </div>
        
        <div class="connection-info">
          <div class="info-item">
            <span class="label">类型:</span>
            <span class="value">{{ conn.dbType }}</span>
          </div>
          <div class="info-item">
            <span class="label">地址:</span>
            <span class="value">{{ conn.host }}:{{ conn.port }}</span>
          </div>
          <div class="info-item">
            <span class="label">数据库:</span>
            <span class="value">{{ conn.databaseName }}</span>
          </div>
          <div class="info-item">
            <span class="label">用户名:</span>
            <span class="value">{{ conn.username }}</span>
          </div>
        </div>
        
        <div class="connection-actions">
          <el-button-group>
            <el-button 
              v-if="!conn.isDefault" 
              type="primary" 
              link 
              @click="setAsDefault(conn)"
              :loading="conn.isLoading"
            >
              设为默认
            </el-button>
            <el-button type="info" link @click="editConnection(conn)">编辑</el-button>
            <el-button type="danger" link @click="deleteConnectionConfirm(conn)">删除</el-button>
          </el-button-group>
        </div>
      </el-card>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  getUserConnections,
  getDefaultConnection,
  createConnection,
  updateConnection,
  deleteConnection as apiDeleteConnection,
  setDefaultConnection,
  testConnection as apiTestConnection,
  clearConnectionMetadata
} from '../api/dbConnection'

// 数据和状态
const dialogVisible = ref(false)
const isEditing = ref(false)
const connections = ref([])
const loading = ref(true)
const saving = ref(false)
const testing = ref(false)
const currentConnectionId = ref(null)

// 默认端口
const defaultPorts = {
  mysql: 3306,
  postgresql: 5432,
  oracle: 1521,
  sqlserver: 1433
}

// 表单和验证规则
const connectionFormRef = ref(null)
const connectionForm = reactive({
  name: '',
  dbType: 'mysql',
  host: '',
  port: 3306,
  databaseName: '',
  username: '',
  password: '',
  isDefault: false
})

const rules = {
  name: [
    { required: true, message: '请输入连接名称', trigger: 'blur' },
    { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
  ],
  dbType: [
    { required: true, message: '请选择数据库类型', trigger: 'change' }
  ],
  host: [
    { required: true, message: '请输入主机地址', trigger: 'blur' }
  ],
  port: [
    { required: true, message: '请输入端口号', trigger: 'blur' },
    { type: 'number', message: '端口必须为数字', trigger: 'blur' }
  ],
  databaseName: [
    { required: true, message: '请输入数据库名称', trigger: 'blur' }
  ],
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' }
  ]
}

// 初始化
onMounted(async () => {
  await loadConnections()
})

// 加载所有连接
async function loadConnections() {
  loading.value = true
  try {
    connections.value = await getUserConnections()
  } catch (error) {
    ElMessage.error(error.message || '加载数据库连接失败')
  } finally {
    loading.value = false
  }
}

// 打开创建对话框
function openCreateDialog() {
  isEditing.value = false
  resetForm()
  dialogVisible.value = true
}

// 打开编辑对话框
function editConnection(connection) {
  isEditing.value = true
  currentConnectionId.value = connection.id
  
  // 填充表单
  Object.keys(connectionForm).forEach(key => {
    if (key in connection) {
      connectionForm[key] = connection[key]
    }
  })
  
  if (connection.dbType) {
    connectionForm.dbType = connection.dbType.toLowerCase()
  }
  
  // 清空密码，因为后端不会返回密码
  connectionForm.password = ''
  
  dialogVisible.value = true
}

// 保存连接
async function saveConnection() {
  if (!connectionFormRef.value) return
  
  await connectionFormRef.value.validate(async (valid) => {
    if (!valid) return
    
    saving.value = true
    try {
      if (isEditing.value) {
        await updateConnection(currentConnectionId.value, connectionForm)
        ElMessage.success('数据库连接已更新')
      } else {
        await createConnection(connectionForm)
        ElMessage.success('数据库连接已创建')
      }
      
      await loadConnections()
      closeDialog()
    } catch (error) {
      ElMessage.error(error.message || '保存数据库连接失败')
    } finally {
      saving.value = false
    }
  })
}

// 测试当前表单中的连接
async function testCurrentConnection() {
  if (!connectionFormRef.value) return
  
  // 部分验证表单
  const requiredFields = ['dbType', 'host', 'port', 'databaseName', 'username', 'password']
  const formValid = requiredFields.every(field => {
    const fieldValue = connectionForm[field]
    return fieldValue !== undefined && fieldValue !== ''
  })
  
  if (!formValid) {
    ElMessage.warning('请填写必要的连接信息后再测试')
    return
  }
  
  testing.value = true
  try {
    const result = await apiTestConnection(connectionForm)
    ElMessage.success('连接测试成功')
    
    // 清除元数据缓存，以便重新获取最新的数据库结构
    try {
      await clearConnectionMetadata(currentConnectionId.value)
    } catch (error) {
      console.error('清除元数据缓存失败:', error)
    }
  } catch (error) {
    ElMessage.error(error.message || '连接测试失败')
  } finally {
    testing.value = false
  }
}

// 设置为默认连接
async function setAsDefault(connection) {
  try {
    // 标记当前连接为加载中
    const index = connections.value.findIndex(c => c.id === connection.id)
    if (index !== -1) {
      connections.value[index] = { ...connections.value[index], isLoading: true }
    }
    
    await setDefaultConnection(connection.id)
    ElMessage.success(`已将 "${connection.name}" 设为默认连接`)
    await loadConnections()
  } catch (error) {
    ElMessage.error(error.message || '设置默认连接失败')
    
    // 移除加载状态
    const index = connections.value.findIndex(c => c.id === connection.id)
    if (index !== -1) {
      connections.value[index] = { ...connections.value[index], isLoading: false }
    }
  }
}

// 删除确认
async function deleteConnectionConfirm(connection) {
  try {
    await ElMessageBox.confirm(
      `确定要删除连接 "${connection.name}" 吗？此操作不可恢复。`,
      '删除确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    await apiDeleteConnection(connection.id)
    ElMessage.success('连接已删除')
    await loadConnections()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error(error.message || '删除连接失败')
    }
  }
}

// 处理数据库类型变更
function handleDbTypeChange() {
  // 根据数据库类型更新默认端口
  if (connectionForm.dbType && defaultPorts[connectionForm.dbType]) {
    connectionForm.port = defaultPorts[connectionForm.dbType]
  }
}

// 关闭对话框
function closeDialog() {
  dialogVisible.value = false
  resetForm()
}

// 重置表单
function resetForm() {
  if (connectionFormRef.value) {
    connectionFormRef.value.resetFields()
  }
  
  // 手动重置表单内容
  connectionForm.name = ''
  connectionForm.dbType = 'mysql'
  connectionForm.host = ''
  connectionForm.port = defaultPorts.mysql
  connectionForm.databaseName = ''
  connectionForm.username = ''
  connectionForm.password = ''
  connectionForm.isDefault = false
  
  currentConnectionId.value = null
}
</script>

<style scoped>
.db-connection-manager {
  padding: 20px;
}

.connection-manager-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.connections-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
  gap: 20px;
}

.connection-card {
  position: relative;
  transition: all 0.3s;
}

.connection-card.is-default {
  border: 1px solid var(--el-color-success);
}

.connection-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.connection-header h4 {
  margin: 0;
  font-size: 16px;
}

.connection-info {
  margin-bottom: 15px;
}

.info-item {
  display: flex;
  margin-bottom: 5px;
}

.info-item .label {
  width: 80px;
  color: #909399;
}

.connection-actions {
  display: flex;
  justify-content: flex-end;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 24px;
}

.loading-wrapper {
  padding: 20px;
}

.empty-state {
  display: flex;
  justify-content: center;
  padding: 40px 0;
}
</style> 